#include<vector>
using namespace std;



class MyCircularDeque {
private:
    int capacity;
    vector<int>arr;
    int front, rear;

public:
    /** Initialize your data structure here. Set the size of the deque to be k. */
    MyCircularDeque(int k):capacity(k+1), arr(capacity), front(0),rear(0){

    }

    /** Adds an item at the front of Deque. Return true if the operation is successful. */
    bool insertFront(int value) {
        if (isFull()) return false;
        front = (front - 1 + capacity) % capacity;
        arr[front] = value;
        return true;
    }

    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
    bool insertLast(int value) {
        if (isFull()) return false;
        arr[rear] = value;
        rear = (rear + 1) % capacity;
        return true;
    }

    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
    bool deleteFront() {
        if (isEmpty()) return false;
        front = (front + 1) % capacity;
        return true;
    }

    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
    bool deleteLast() {
        if (isEmpty()) return false;
        rear = (rear - 1 + capacity) % capacity;
        return true;
    }

    /** Get the front item from the deque. */
    int getFront() {
        if (isEmpty()) return -1;
        return arr[front];
    }

    /** Get the last item from the deque. */
    int getRear() {
        if (isEmpty()) return -1;
        return arr[(rear - 1 + capacity) % capacity];
    }

    /** Checks whether the circular deque is empty or not. */
    bool isEmpty() {
        return front == rear;
    }

    /** Checks whether the circular deque is full or not. */
    bool isFull() {
        return front == (rear + 1) % capacity;
    }
};

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */
//class MyCircularDeque {
//private:
//    struct Node {
//        int val;
//        Node* prev;
//        Node* next;
//        Node(int val) :val(val), prev(NULL), next(NULL) {
//
//        }
//    };
//
//    Node* head;
//    int capacity;
//    int size;
//
//    void remove(Node* node) {
//        node->prev->next = node->next;
//        node->next->prev = node->prev;
//    }
//
//    void insert(Node* prev, Node* node) {
//        node->next = prev->next;
//        prev->next->prev = node;
//        prev->next = node;
//        node->prev = prev;
//    }
//
//public:
//    /** Initialize your data structure here. Set the size of the deque to be k. */
//    MyCircularDeque(int k):head(new Node(-1)),capacity(k),size(0){
//        head->prev = head;
//        head->next = head;
//    }
//
//    /** Adds an item at the front of Deque. Return true if the operation is successful. */
//    bool insertFront(int value) {
//        if (size >= capacity)
//            return false;
//        ++size;
//        Node* node = new Node(value);
//        insert(head, node);
//        return true;
//    }
//
//    /** Adds an item at the rear of Deque. Return true if the operation is successful. */
//    bool insertLast(int value) {
//        if (size >= capacity)
//            return false;
//        ++size;
//        Node* node = new Node(value);
//        insert(head->prev, node);
//        return true;
//    }
//
//    /** Deletes an item from the front of Deque. Return true if the operation is successful. */
//    bool deleteFront() {
//        if (size == 0) return false;
//        --size;
//        Node* node = head->next;
//        remove(node);
//        delete node;
//        return true;
//    }
//
//    /** Deletes an item from the rear of Deque. Return true if the operation is successful. */
//    bool deleteLast() {
//        if (size == 0) return false;
//        --size;
//        Node* node = head->prev;
//        remove(node);
//        delete node;
//        return true;
//    }
//
//    /** Get the front item from the deque. */
//    int getFront() {
//        return head->next->val;
//    }
//
//    /** Get the last item from the deque. */
//    int getRear() {
//        return head->prev->val;
//    }
//
//    /** Checks whether the circular deque is empty or not. */
//    bool isEmpty() {
//        return size == 0;
//    }
//
//    /** Checks whether the circular deque is full or not. */
//    bool isFull() {
//        return size == capacity;
//    }
//};

/**
 * Your MyCircularDeque object will be instantiated and called as such:
 * MyCircularDeque* obj = new MyCircularDeque(k);
 * bool param_1 = obj->insertFront(value);
 * bool param_2 = obj->insertLast(value);
 * bool param_3 = obj->deleteFront();
 * bool param_4 = obj->deleteLast();
 * int param_5 = obj->getFront();
 * int param_6 = obj->getRear();
 * bool param_7 = obj->isEmpty();
 * bool param_8 = obj->isFull();
 */